package nftrainer.taskmanager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import language.Languages;
import language.TextHandler;

import nftrainer.dbconnect.DBConnector;
import nftrainer.dbconnect.interfaces.IDBConnector;
import nftrainer.helper.NFMap;
import nftrainer.taskmanager.interfaces.ITaskManager;

public class TaskManager implements ITaskManager {
	
	private Task task;
	private IDBConnector dbcon;
	private Random random;
	
	private List<String> subtasks;
	
	private String GETTASKTABLE = "SELECT * FROM aufgabe";
	private String sql, tableName;
	
	private TextHandler textHandler;
	
	public TaskManager (TextHandler textHandler) {
		this.textHandler = textHandler;
	}
	
	private void init() {
		dbcon = new DBConnector();
		random = new Random();
		subtasks = new ArrayList<String>();
		task = new Task();
	}

	@Override
	public void loadRandomTask() {
		init();
		dbcon.openConnection();
		this.loadSubtasks();
		task.setID(random.nextInt(dbcon.getTaskAmount(textHandler.getActualLanguage()))+1);
		//task.setID(8);
		dbcon.getRandomTask(task, textHandler.getActualLanguage());
		String sql, sql1;
		switch (textHandler.getActualLanguage()) {
		case de_DE:
			sql = GETTASKTABLE+task.getID();
			sql1 = sql + "_1";
			break;
		case en_GB:
			sql = GETTASKTABLE+task.getID()+"_en";
			sql1 = GETTASKTABLE+task.getID()+"_1_en";
			break;
		default:
			sql = GETTASKTABLE+task.getID();
			sql1 = sql + "_1";
			break;
		}
		task.setTable(dbcon.loadTaskTable(sql));
		tableName = "aufgabe"+task.getID();
		if (task.getNF() == 0) {
			task.setTable1NF(dbcon.loadTaskTable(sql1));
			tableName+="_1";
		} else {
			task.setTable1NF(task.getTable().get(0));
		}
		if (textHandler.getActualLanguage().equals(Languages.en_GB)) {
			tableName+="_en";
		}
		dbcon.closeConnection();
		Collections.sort(task.getNotFirstNF());
		Collections.sort(task.getPrimary());
	}
	
	private void loadSubtasks() {
		subtasks.add(textHandler.printf("subtasks.first"));
		subtasks.add(textHandler.printf("subtasks.second"));
		subtasks.add(textHandler.printf("subtasks.third"));
		subtasks.add(textHandler.printf("subtasks.fourth"));
		subtasks.add(textHandler.printf("subtasks.fifth"));
		subtasks.add(textHandler.printf("subtasks.sixth"));
	}

	@Override
	public boolean isFirstNF() {
		return (task.getNF() == 1 ? true : false);
	}

	@Override
	public List<String> getNotFirstNFColumns() {
		return task.getNotFirstNF();
	}

	@Override
	public List<NFMap> getFunctional() {
		return task.getFunctional();
	}

	@Override
	public List<String> getPrimaryKey() {
		return task.getPrimary();
	}

	@Override
	public List<NFMap> getSecondNF() {
		return task.getSecondNF();
	}

	@Override
	public List<NFMap> getThirdNF() {
		return task.getThirdNF();
	}
	
	@Override
	public HashMap<Integer, String[][]> getTaskTable() {
		return task.getTable();
	}
	
	@Override
	public HashMap<Integer, String[][]> getTaskTable1NF() {
		return task.getTable1NF();
	}
	
	@Override
	public HashMap<Integer, String[][]> getTaskTables2NF() {
		this.loadSecondTaskTable();
		return task.getSecondNFTable();
	}
	
	@Override
	public HashMap<Integer, String[][]> getTaskTables3NF() {
		this.loadThirdTaskTable();
		return task.getThirdNFTable();
	}
	
	private void loadSecondTaskTable() {
		dbcon.openConnection();
		List<NFMap> secondNF = this.getSecondNF();
		int size = secondNF.size();
		for (int i = 0; i < size; i++) {
			sql = "SELECT DISTINCT "+secondNF.get(i).getAllAsString()+" FROM "+tableName;
			task.addToSecondNFTable(i, dbcon.loadTaskTable(sql));
		}
		dbcon.closeConnection();
	}
	
	private void loadThirdTaskTable () {
		dbcon.openConnection();
		List<NFMap> thirdNF = this.getThirdNF();
		int size = thirdNF.size();
		for (int i = 0; i < size; i++) {
			sql = "SELECT DISTINCT "+thirdNF.get(i).getAllAsString()+" FROM "+tableName;
			task.addToThirdNFTable(i, dbcon.loadTaskTable(sql));
		}
		dbcon.closeConnection();
	}
	
	@Override
	public List<String> getSubTasks () {
		return subtasks;
	}
	
	@Override
	public int getSubtaskAmount() {
		return subtasks.size();
	}
	
	@Override
	public String getNextSubtask(int actualSubtask) {
		return subtasks.get(actualSubtask);
	}

	@Override
	public String getTaskText() {
		return this.task.getText();
	}

}
